// vite/vite-plugin-icon-dts.ts
import fs from 'fs-extra';
import glob from 'fast-glob';
import path from 'path';
import { useThrottleFn } from '@vueuse/core';
import type { PluginOption } from 'vite';

// glob 默认只支持 / 作为路径分隔符，windows 下会出现问题
const normalizePath = (_path: string) => _path.replace(/\\/g, '/');

interface IconDtsOptions {
  /** svg 图标文件的路径 */
  iconDirs: string;
  /** 输出的dts文件的路径 */
  dts: string;
  /** 监听变化的延迟时间 */
  delay: number;
  /** 接口名称 */
  interfaceName: string;
}

const defualtOptions: IconDtsOptions = {
  iconDirs: 'src/icons/',
  dts: 'svg-icons.d.ts',
  delay: 200,
  interfaceName: 'BaseSvgIconPath',
};

/**
 * svg 图标路径生成dts文件
 */
export function svgIconPathOption(options: Partial<IconDtsOptions> = {}): PluginOption {
  const finalOptions: IconDtsOptions = { ...defualtOptions, ...options };
  const { delay, interfaceName } = finalOptions;
  let { iconDirs, dts } = finalOptions;
  iconDirs = normalizePath(iconDirs);
  dts = normalizePath(dts);
  let watcher: fs.FSWatcher | undefined = undefined;
  return {
    name: 'svg-icons-dts',
    buildStart: () => {
      if (!fs.existsSync(iconDirs)) {
        console.error(`${iconDirs}不存在，请检查`);
        return;
      }
      const update = () => {
        let assets: string[] = glob.sync(`${iconDirs}/**/*.svg`, {});
        assets = assets.map((i: string) => i.replace(iconDirs, '').replace('.svg', '').replace('/', '-').replace(/^-+/, ''));
        let output = `interface ${interfaceName} {\n`;
        assets.forEach((_item) => {
          output += `  '${_item}': string;\n`;
        });
        output += `}\n`;
        const base = path.dirname(dts);
        fs.ensureDirSync(base);
        fs.writeFileSync(dts, output);
      };

      const debounceLogic = useThrottleFn(update, delay);
      // 监听到文件变化，就重新写一遍
      watcher = fs.watch(iconDirs, { recursive: true }, () => {
        debounceLogic();
      });
      update();
    },
    buildEnd: () => {
      watcher && watcher.close();
    },
  };
}
